﻿using System;
using System.Linq;
using System.Linq.Expressions;
using Abp.IdentityServer4;
using Abp.Zero.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Camc.OutsourceProcession.Authorization.Roles;
using Camc.OutsourceProcession.Authorization.Users;
using Camc.OutsourceProcession.Chat;
using Camc.OutsourceProcession.Editions;
using Camc.OutsourceProcession.Friendships;
using Camc.OutsourceProcession.MultiTenancy;
using Camc.OutsourceProcession.MultiTenancy.Accounting;
using Camc.OutsourceProcession.MultiTenancy.Payments;
using Camc.OutsourceProcession.Storage;
using Abp.EntityFrameworkCore;
using Abp.Organizations;
using Abp.Runtime.Session;
using Camc.OutsourceProcession.ProduceTask;
using Camc.OutsourceProcession.Customer;
using Camc.OutsourceProcession.TaskProcess.Process;
using Camc.OutsourceProcession.TaskProcess.Request;
using Camc.OutsourceProcession.TaskProcess.Station;
using Camc.OutsourceProcession.TaskProcess.TaskLine;
using Camc.OutsourceProcession.AppUserInfos;
using Camc.OutsourceProcession.ManufacturingEquipment;
using Camc.OutsourceProcession.Order;
using Camc.OutsourceProcession.TaskProcess.Worker;
using Camc.OutsourceProcession.Organization;
using Camc.OutsourceProcession.Printer;
using Microsoft.EntityFrameworkCore.Metadata;

namespace Camc.OutsourceProcession.EntityFrameworkCore
{
    public class SCDDbContext : AbpDbContext
	{


		protected virtual string[] CurrentCompanyCodeList => GetCurrentCompanyCodeOrNull();

		public IPrincipalAccessor PrincipalAccessor { get; set; }

		protected virtual bool IsCompanyCodeFilterEnabled => CurrentUnitOfWorkProvider?.Current?.IsFilterEnabled("MayHaveCompanyCode") == true;

		/* Define an IDbSet for each entity of the application */

		public virtual DbSet<Aaa> Aaas { get; set; }

		public virtual DbSet<ProduceTask.Order> Orders { get; set; }

		public virtual DbSet<Process> Processes { get; set; }

		public virtual DbSet<Contact> Contacts { get; set; }

		public virtual DbSet<SpecialTool> SpecialTools { get; set; }

		public virtual DbSet<ProductLog> ProductLogs { get; set; }

        public virtual DbSet<AppUserInfo> AppUserInfos { get; set; }
        //导管管理

        public virtual DbSet<NodeBase> NodeBases { get; set; }
		public virtual DbSet<NodeForInstance> NodeForInstances { get; set; }
		public virtual DbSet<NodeForTemplate> NodeForTemplates { get; set; }
		public virtual DbSet<WorkStation> WorkStations { get; set; }
		public virtual DbSet<LineInstance> LineInstances { get; set; }
		public virtual DbSet<LineInstanceExecuteHistory> LineInstanceExecuteHistorys { get; set; }
		public virtual DbSet<LineTemplate> LineTemplates { get; set; }
		public virtual DbSet<RequestBase> RequestBases { get; set; }
		public virtual DbSet<WorkingTeam> WorkingTeams { get; set; }

		//外协加工

		public virtual DbSet<PrintEquipment> PrintEquipments { get; set; }
		public virtual DbSet<ProductionOrder> ProductionOrders { get; set; }
		public virtual DbSet<ExecuteHistory> ExecuteHistories { get; set; }
		public virtual DbSet<Equipment> Equipments { get; set; }
		public virtual DbSet<MyPrinter> MyPrinters { get; set; }
		public SCDDbContext(DbContextOptions<SCDDbContext> options)
            : base(options)
        {
            
        }

     

		protected virtual string[] GetCurrentCompanyCodeOrNull()
        {
	        var userOuClaim = PrincipalAccessor.Principal?.Claims.FirstOrDefault(c => c.Type == "Application_CompanyCode");
	        if (string.IsNullOrEmpty(userOuClaim?.Value))
	        {
		        return null;
	        }

	        return userOuClaim.Value?.Split(',');


        }

        protected override bool ShouldFilterEntity<TEntity>(IMutableEntityType entityType)
        {
	        if (typeof(IMayHaveCompanyCode).IsAssignableFrom(typeof(TEntity)))
	        {
		        return true;
	        }

	        return base.ShouldFilterEntity<TEntity>(entityType);
        }

        protected override Expression<Func<TEntity, bool>> CreateFilterExpression<TEntity>()
        {
	        var expression = base.CreateFilterExpression<TEntity>();

	        if (typeof(IMayHaveCompanyCode).IsAssignableFrom(typeof(TEntity)))
	        {
		        Expression<Func<TEntity, bool>> mayHaveCompanyCodeFilter = e => CurrentCompanyCodeList.Contains(((IMayHaveCompanyCode)e).CompanyCode) || (IsCompanyCodeFilterEnabled == CurrentCompanyCodeList.Contains(((IMayHaveCompanyCode)e).CompanyCode));
		        expression = expression == null ? mayHaveCompanyCodeFilter : CombineExpressions(expression, mayHaveCompanyCodeFilter);
	        }

	        return expression;
        }
	}
}
